package com.hafiery.sdk.bluetooth.api;

import android.text.TextUtils;
import com.hafiery.sdk.bluetooth.IBlueToothAction;
import com.hafiery.sdk.bluetooth.transport.adapter.*;
import com.hafiery.sdk.bluetooth.transport.callback.CallBackHandler;
import com.hafiery.sdk.bluetooth.transport.callback.Callback;
import com.hafiery.sdk.bluetooth.transport.constant.OpCode;
import com.hafiery.sdk.bluetooth.transport.req.RequestData;
import com.hafiery.sdk.bluetooth.util.ByteUtil;

import java.util.concurrent.Callable;

public class BlueToothApiImp implements IBlueToothApi{
    private IBlueToothAction mClient;

    public BlueToothApiImp(IBlueToothAction mClient) {
        this.mClient = mClient;
    }

    @Override
    public void getDeviceType(Callback<String> callback) {
        mClient.write(new RequestData.Builder()
                .cmd(OpCode.GET_DEVICE_TYPE)
                .build(),new CallBackHandler<>(callback,new AscillStringAdapter()));
    }

    @Override
    public void getDeviceID(Callback<String> callback) {
        mClient.write(new RequestData.Builder()
                .cmd(OpCode.GET_DEVICE_ID)
                .build(),new CallBackHandler<>(callback,new AscillStringAdapter()));
    }

    @Override
    public void getDeviceTime(Callback<Integer> callback) {
        mClient.write(new RequestData.Builder()
                .cmd(OpCode.GET_DEVICE_TIME)
                .build(),new CallBackHandler<>(callback,new BytesFourToIntAdapter()));
    }

    @Override
    public void setDeviceTime(long timestamp,Callback<String> callback) {
        mClient.write(new RequestData.Builder()
                .cmd(OpCode.SET_DEVICE_TIME)
                        .payload(ByteUtil.intToBytesLittle((int) (timestamp/1000)))
                .build(),new CallBackHandler<>(callback,new NobodyAdapter()));
    }

    @Override
    public void getDeviceVersion(Callback<String> callback) {
        mClient.write(new RequestData.Builder()
                .cmd(OpCode.GET_DEVICE_VERSION)
                .build(),new CallBackHandler<>(callback,new AscillStringAdapter()));
    }

    @Override
    public void upgradeDeviceVersion(Callback<String> callback) {
        mClient.write(new RequestData.Builder()
                .cmd(OpCode.UPGRADE_DEVICE_VERSION)
                .build(),new CallBackHandler<>(callback,new NobodyAdapter()));
    }

    @Override
    public void getDeviceMAC(Callback<String> callback) {
        mClient.write(new RequestData.Builder()
                .cmd(OpCode.GET_DEVICE_MAC)
                .build(),new CallBackHandler<>(callback,new StringAdapter()));
    }

    @Override
    public void getDevicePower(Callback<Integer> callback) {
        mClient.write(new RequestData.Builder()
                .cmd(OpCode.GET_DEVICE_POWER)
                .build(),new CallBackHandler<>(callback,new Int8Adapter()));
    }

    @Override
    public void getDeviceRom(Callback<Integer> callback) {
        mClient.write(new RequestData.Builder()
                .cmd(OpCode.GET_DEVICE_ROM)
                .build(),new CallBackHandler<>(callback,new Int32Adapter()));
    }

    @Override
    public void getDeviceRomUsed(Callback<Integer> callback) {
        mClient.write(new RequestData.Builder()
                .cmd(OpCode.GET_DEVICE_ROM_USED)
                .build(),new CallBackHandler<>(callback,new Int32Adapter()));
    }

    @Override
    public void getDeviceRomUnUsed(Callback<Integer> callback) {
        mClient.write(new RequestData.Builder()
                .cmd(OpCode.GET_DEVICE_ROM_UNUSED)
                .build(),new CallBackHandler<>(callback,new Int32Adapter()));
    }

    @Override
    public void getDeviceBindInfo(Callback<String> callback) {
        mClient.write(new RequestData.Builder()
                .cmd(OpCode.GET_DEVICE_BIND)
                .build(),new CallBackHandler<>(callback,new AscillStringAdapter()));
    }

    @Override
    public void bindDevice(String bindInfo, Callback<String> callback) {
        mClient.write(new RequestData.Builder()
                .cmd(OpCode.SET_DEVICE_BIND)
                .payload(bindInfo.getBytes())
                .build(),new CallBackHandler<>(callback,new NobodyAdapter()));
    }

    @Override
    public void unBindDevice(Callback<String> callback) {
        mClient.write(new RequestData.Builder()
                .cmd(OpCode.SET_DEVICE_UNBIND)
                .build(),new CallBackHandler<>(callback,new NobodyAdapter()));
    }

    @Override
    public void getBleName(Callback<String> callback) {
        mClient.write(new RequestData.Builder()
                .cmd(OpCode.GET_BLE_NAME)
                .build(),new CallBackHandler<>(callback,new AscillStringAdapter()));
    }

    @Override
    public void bindBleName(String name,Callback<String> callback) {
        mClient.write(new RequestData.Builder()
                .cmd(OpCode.SET_BLE_NAME)
                .payload(name.getBytes())
                .build(),new CallBackHandler<>(callback,new NobodyAdapter()));
    }

    @Override
    public void getWifiStatus(Callback<Integer> callback) {
        mClient.write(new RequestData.Builder()
                .cmd(OpCode.GET_WIFI_STATUS)
                .build(),new CallBackHandler<>(callback,new Int8Adapter()));
    }

    @Override
    public void openOrCloseWifi(boolean b, Callback<String> callback) {
        mClient.write(new RequestData.Builder()
                .cmd(b?OpCode.OPEN_WIFI:OpCode.CLOSE_WIFI)
                .build(),new CallBackHandler<>(callback,new NobodyAdapter()));
    }

    @Override
    public void getCurrentWifiRssi(Callback<Integer> callback) {
        mClient.write(new RequestData.Builder()
                .cmd(OpCode.WIFI_RSSI)
                .build(),new CallBackHandler<>(callback,new Int8Adapter()));
    }

    @Override
    public void getCurrentWifi(Callback<String> callback) {
        mClient.write(new RequestData.Builder()
                .cmd(OpCode.GET_CURRENT_WIFI)
                .build(),new CallBackHandler<>(callback,new AscillStringAdapter()));
    }

    @Override
    public void connectWifi(String ssid,String password, Callback<String> callback) {
//        String[] list=wifi.split(":");
//        String ssid=list[0];
//        String password = list[1];
        if(TextUtils.isEmpty(ssid))
            return;
        byte ssidLen=(byte) ssid.length();
        byte passwordLen =(byte) password.length();

        byte[] payload=new byte[1+ssid.length()+1+password.length()];
        payload[0]=ssidLen;
        payload[1+ssid.length()]=passwordLen;
        System.arraycopy(ssid.getBytes(),0,payload,1,ssidLen);
        System.arraycopy(password.getBytes(),0,payload,2+ssid.length(),passwordLen);

        mClient.write(new RequestData.Builder()
                .cmd(OpCode.CONNECT_WIFI)
                        .payload(payload)
                .build(),new CallBackHandler<>(callback,new NobodyAdapter()));
    }

    @Override
    public void disConnectWifi(String ssid, Callback<String> callback) {
        mClient.write(new RequestData.Builder()
                .cmd(OpCode.DISCONNECT_WIFI)
                .payload(ssid.getBytes())
                .build(),new CallBackHandler<>(callback,new NobodyAdapter()));
    }


    @Override
    public void getAutoRecordStatus(Callback<Integer> callback) {
        mClient.write(new RequestData.Builder()
                .cmd(OpCode.GET_AUTO_RECORD_STATUS)
                .build(),new CallBackHandler<>(callback,new Int8Adapter()));
    }

    @Override
    public void setAutoRecordStatus(boolean b, Callback<String> callback) {
        mClient.write(new RequestData.Builder()
                .cmd(OpCode.SET_AUTO_RECORD_STATUS)
                .payload(new byte[]{(byte) (b ? 0x01 : 0x00)})
                .build(),new CallBackHandler<>(callback,new NobodyAdapter()));
    }

    @Override
    public void getOriginRecordStatus(Callback<Integer> callback) {
        mClient.write(new RequestData.Builder()
                .cmd(OpCode.GET_ORIGIN_RECORD_STATUS)
                .build(),new CallBackHandler<>(callback,new Int8Adapter()));
    }

    @Override
    public void setOriginRecordStatus(boolean b, Callback<String> callback) {
        mClient.write(new RequestData.Builder()
                .cmd(OpCode.SET_ORIGIN_RECORD_STATUS)
                .payload(new byte[]{(byte) (b ? 0x01 : 0x00)})
                .build(),new CallBackHandler<>(callback,new NobodyAdapter()));
    }

    @Override
    public void getRecordModel(Callback<Integer> callback) {
        mClient.write(new RequestData.Builder()
                .cmd(OpCode.GET_RECORD_MODEL)
                .build(),new CallBackHandler<>(callback,new Int8Adapter()));
    }

    @Override
    public void setRecordModel(int model,Callback<String> callback) {
        mClient.write(new RequestData.Builder()
                .cmd(OpCode.SET_RECORD_MODEL)
                        .payload(new byte[]{(byte) model})
                .build(),new CallBackHandler<>(callback,new NobodyAdapter()));
    }

    @Override
    public void getRecordFormat(Callback<Integer> callback) {
        mClient.write(new RequestData.Builder()
                .cmd(OpCode.GET_RECORD_FORMAT)
                .build(),new CallBackHandler<>(callback,new Int8Adapter()));
    }

    @Override
    public void getRecordLightStatus(Callback<Integer> callback) {
        mClient.write(new RequestData.Builder()
                .cmd(OpCode.GET_RECORD_LIGHT_STATUS)
                .build(),new CallBackHandler<>(callback,new Int8Adapter()));
    }

    @Override
    public void setRecordLightStatus(boolean b, Callback<String> callback) {
        mClient.write(new RequestData.Builder()
                .cmd(OpCode.SET_RECORD_LIGHT)
                .payload(new byte[]{(byte) (b ? 0x01 : 0x00)})
                .build(),new CallBackHandler<>(callback,new NobodyAdapter()));
    }

    @Override
    public void getRecordStatus(Callback<Integer> callback) {
        mClient.write(new RequestData.Builder()
                .cmd(OpCode.GET_RECORD_STATUS)
                .build(),new CallBackHandler<>(callback,new Int8Adapter()));
    }

    @Override
    public void getCurrentRecordFileName(Callback<String> callback) {
        mClient.write(new RequestData.Builder()
                .cmd(OpCode.GET_CURRENT_RECORD_FILENAME)
                .build(),new CallBackHandler<>(callback,new AscillStringAdapter()));
    }

    @Override
    public void startRecord(Callback<String> callback) {
        mClient.write(new RequestData.Builder()
                .cmd(OpCode.START_RECORD)
                .build(),new CallBackHandler<>(callback,new NobodyAdapter()));
    }

    @Override
    public void stopRecord(Callback<String> callback) {
        mClient.write(new RequestData.Builder()
                .cmd(OpCode.STOP_RECORD)
                .build(),new CallBackHandler<>(callback,new NobodyAdapter()));
    }

    @Override
    public void pauseRecord(Callback<String> callback) {
        mClient.write(new RequestData.Builder()
                .cmd(OpCode.PAUSE_RECORD)
                .build(),new CallBackHandler<>(callback,new NobodyAdapter()));
    }

    @Override
    public void resumeRecord(Callback<String> callback) {
        mClient.write(new RequestData.Builder()
                .cmd(OpCode.RESUME_RECORD)
                .build(),new CallBackHandler<>(callback,new NobodyAdapter()));
    }

    @Override
    public void getRecordList(int page, int pageSize, Callback<Files> callback) {
        byte[] payload = new byte[2];
        payload[0] = (byte) (0x000000ff & page);
        payload[1] = (byte) (0x000000ff & pageSize);
        mClient.write(new RequestData.Builder()
                .cmd(OpCode.GET_RECORD_LIST)
                        .payload(payload)
                .build(),new CallBackHandler<>(callback,new RecordFilesAdapter()));
    }

    @Override
    public void removeRecordFile(String filename, Callback<String> callback) {
        mClient.write(new RequestData.Builder()
                .cmd(OpCode.REMOVE_RECORD_FILE)
                .payload(filename.getBytes())
                .build(),new CallBackHandler<>(callback,new NobodyAdapter()));
    }

    @Override
    public void formatRom(Callback<String> callback) {
        mClient.write(new RequestData.Builder()
                .cmd(OpCode.FORMAT_ROM)
                .build(),new CallBackHandler<>(callback,new NobodyAdapter()));
    }

    @Override
    public void reFactory(Callback<String> callback) {
        mClient.write(new RequestData.Builder()
                .cmd(OpCode.RE_FACTORY)
                .build(),new CallBackHandler<>(callback,new NobodyAdapter()));
    }

    @Override
    public void openOrCloseLiveTransform(boolean open, Callback<String> callback) {
        mClient.write(new RequestData.Builder()
                .cmd(open?OpCode.OPENLIVETRANSFORM:OpCode.CLOSELIVETRANSFORM)
                .build(),new CallBackHandler<>(callback,new NobodyAdapter()));
    }

    @Override
    public void pauseLiveTransform(Callback<String> callback) {
        mClient.write(new RequestData.Builder()
                .cmd(OpCode.PAUSE_LIVE_TRANSFORM)
                .build(),new CallBackHandler<>(callback,new NobodyAdapter()));
    }

    @Override
    public void resumeLiveTransform(Callback<String> callback) {
        mClient.write(new RequestData.Builder()
                .cmd(OpCode.RESUME_LIVE_TRANSFORM)
                .build(),new CallBackHandler<>(callback,new NobodyAdapter()));
    }
}
